package com.fengye.fdfs;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.StorageClient1;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.io.*;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author fengyexjtu@126.com
 * @date 2022年05月22日 6:32 PM
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class FileService {

    private final StorageClient1 storageClient1;
    private final FileRepository repository;
    private final ObjectMapper objectMapper;

    /**
     * 上传文件
     *
     * @param file     文件对象
     * @param fileName 文件名
     * @return 文件 id 如: group1/M00/00/00/wKgAZ2KBGACAGs2IAANGq0XiRQw511.jpg
     */
    public String uploadFile(File file, String fileName) {
        return uploadFile(file, fileName, null);
    }

    /**
     * 上传文件,并设置文件的元信息
     *
     * @param file     文件对象
     * @param fileName 文件名
     * @param metaList 文件元数据
     * @return 文件 id 如: group1/M00/00/00/wKgAZ2KBGACAGs2IAANGq0XiRQw511.jpg
     */
    public String uploadFile(File file, String fileName, Map<String, String> metaList) {
        try {
            byte[] buff = IOUtils.toByteArray(new FileInputStream(file));
            NameValuePair[] nameValuePairs = null;
            if (metaList != null) {
                nameValuePairs = new NameValuePair[metaList.size()];
                int index = 0;
                for (Map.Entry<String, String> entry : metaList.entrySet()) {
                    String name = entry.getKey();
                    String value = entry.getValue();
                    nameValuePairs[index++] = new NameValuePair(name, value);
                }
            }

            String file_ext_name = fileName.substring(fileName.lastIndexOf(".") + 1);
            String url = storageClient1.upload_file1(buff, file_ext_name, nameValuePairs);
            FileEntity fileEntity = FileEntity.builder()
                    .createTime(new Date())
                    .updateTime(new Date())
                    .originName(fileName)
                    .meta(objectMapper.writeValueAsString(metaList))
                    .remark("测试")
                    .url(url)
                    .build();
            FileEntity fileEntitySaveResult = repository.save(fileEntity);
            log.info("上传成功, {}", fileEntitySaveResult);
            return url;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取文件元数据
     *
     * @param fileId 文件ID
     * @return
     */
    public Map<String, String> getFileMetadata(String fileId) {
        try {
            NameValuePair[] metaList = storageClient1.get_metadata1(fileId);
            if (metaList != null) {
                HashMap<String, String> map = new HashMap<String, String>();
                for (NameValuePair metaItem : metaList) {
                    map.put(metaItem.getName(), metaItem.getValue());
                }
                return map;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 删除文件
     *
     * @param fileId 文件ID
     * @return 删除失败返回-1，否则返回0
     */
    @Transactional
    public int deleteFile(String fileId) {
        try {
            repository.deleteByUrl(fileId);
            return storageClient1.delete_file1(fileId);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return -1;
    }

    /**
     * 下载文件
     *
     * @param fileId  文件ID（上传文件成功后返回的ID）
     * @param outFile 文件下载保存位置
     * @return
     */
    public int downloadFile(String fileId, File outFile) {
        FileOutputStream fos = null;
        try {
            byte[] content = storageClient1.download_file1(fileId);
            fos = new FileOutputStream(outFile);

            IOUtils.copy(new ByteArrayInputStream(content), fos);
            return 0;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return -1;
    }

    /**
     * 分页数据查询
     *
     * @param page 页码
     * @param size 分页大小
     * @return java.util.List<com.fengye.fdfs.FileEntity>
     * @author fengyexjtu@126.com
     * @date 2022/5/22 6:42 PM
     */
    public Page<FileEntity> list(int page, int size) {
        PageRequest pageRequest = PageRequest.of(page, size);
        Page<FileEntity> all = repository.findAll(pageRequest);
        log.info("获取文件列表成功, {}", all.getContent());
        return all;
    }
}
